// 计算一个数的二进制中1的个数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int CountOne(int num)
{
	if(num < 0) {
		printf("Because Of '-',CountOne Cannot Work\n");
		return -1;
	}
	int count = 0;
	while(num) {
		if(1 == (num&1)) {
			++count;
		}
		num >>= 1;
	}
	return count;
}

// 循环32次的解法
int CountTwo(int num)
{
	int count = 0;
	unsigned int flag = 1;
	// 无符号int型，因为没有符号位
	// 当1移动32次之后就变成了负数
	while(flag) {
		if(num&flag) {
			++count;
	 	}
		flag <<= 1;
	}
	return count;
}

// 有几个1就循环几次的解法
// 一个数如果和其减去1之后的结果想与不为0，这样能与多少次就有多少个1
// 一个数减去1如果不为0就表示至少有1位为1
// 减1的时候会借位，将最右边的一个1变为0,以及后面的所有0都变成1，并且之前的位不变
// 而一个数和它减一之后的数想与就是将最右边的1变为0
// 所以有多少个1就能进行这样的操作多少次
int CountThree(int num)
{
	int count = 0;
	while(num) {
		++count;
		num &= (num - 1);
	}
	return count;
}

int main()
{
	int num = 0;
	printf(" Please Input : ");
	scanf("%d", &num);

	printf("%d中1的个数是 : %d\n", num, CountOne(num));
	printf("%d中1的个数是 : %d\n", num, CountTwo(num));
	printf("%d中1的个数是 : %d\n", num, CountThree(num));

	return 0;
}
